/**
 * @file utils.c
 * @brief 算法工具模块实现
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "utils.h"
#include "../../include/score_engine.h"

// 在MSVC下定义M_PI（如果未定义）
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

// 创建算法状态
AlgorithmState* create_algorithm_state(const AlgorithmConfig* config) {
    if (!config) {
        return NULL;
    }
    
    // 分配算法状态内存
    AlgorithmState* state = (AlgorithmState*)malloc(sizeof(AlgorithmState));
    if (!state) {
        return NULL;
    }
    
    // 初始化状态
    memset(state, 0, sizeof(AlgorithmState));
    
    // 分配音频缓存
    if (config->window_size > 0) {
        state->buffer_size = config->window_size;
        state->buffer = (float*)malloc(state->buffer_size * sizeof(float));
        if (!state->buffer) {
            free(state);
            return NULL;
        }
        memset(state->buffer, 0, state->buffer_size * sizeof(float));
    }
    
    // 分配FFT缓存
    if (config->fft_size > 0) {
        state->fft_buffer = (float*)malloc(config->fft_size * sizeof(float));
        state->fft_result = (float*)malloc(config->fft_size * sizeof(float));
        if (!state->fft_buffer || !state->fft_result) {
            if (state->buffer) free(state->buffer);
            if (state->fft_buffer) free(state->fft_buffer);
            if (state->fft_result) free(state->fft_result);
            free(state);
            return NULL;
        }
        memset(state->fft_buffer, 0, config->fft_size * sizeof(float));
        memset(state->fft_result, 0, config->fft_size * sizeof(float));
    }
    
    return state;
}

// 释放算法状态
void free_algorithm_state(AlgorithmState* state) {
    if (!state) {
        return;
    }
    
    // 释放音频缓存
    if (state->buffer) {
        free(state->buffer);
    }
    
    // 释放FFT缓存
    if (state->fft_buffer) {
        free(state->fft_buffer);
    }
    
    if (state->fft_result) {
        free(state->fft_result);
    }
    
    // 释放扩展状态
    if (state->extended_state) {
        free(state->extended_state);
    }
    
    // 释放状态结构体
    free(state);
}

// 获取默认算法配置
AlgorithmConfig get_default_algorithm_config(int sample_rate, int frame_size) {
    AlgorithmConfig config;
    
    // 初始化配置
    memset(&config, 0, sizeof(AlgorithmConfig));
    
    // 设置滤波器参数
    config.low_cut_freq = 20;  // 20Hz高通滤波
    config.high_cut_freq = sample_rate < 32000 ? sample_rate / 2 : 16000; // 最高16kHz
    
    // 设置窗函数参数
    config.window_type = 2;  // 汉明窗
    config.window_size = frame_size;
    
    // 设置FFT参数
    // 计算最接近frame_size的2的幂
    int fft_size = 1;
    while (fft_size < frame_size) {
        fft_size *= 2;
    }
    config.fft_size = fft_size;
    
    // 设置VAD参数
    config.vad_threshold = 0.01f;
    
    return config;
}

// 应用窗函数
int apply_window(float* data, int size, int window_type) {
    if (!data || size <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    // 根据窗类型生成窗系数
    for (int i = 0; i < size; i++) {
        float x = (float)i / (size - 1);
        float window_coef = 1.0f;
        
        switch (window_type) {
            case 0:  // 矩形窗（无变化）
                window_coef = 1.0f;
                break;
                
            case 1:  // 汉宁窗
                window_coef = 0.5f * (1.0f - cosf(2.0f * M_PI * x));
                break;
                
            case 2:  // 汉明窗
                window_coef = 0.54f - 0.46f * cosf(2.0f * M_PI * x);
                break;
                
            case 3:  // 布莱克曼窗
                window_coef = 0.42f - 0.5f * cosf(2.0f * M_PI * x) + 0.08f * cosf(4.0f * M_PI * x);
                break;
                
            default:  // 默认使用汉明窗
                window_coef = 0.54f - 0.46f * cosf(2.0f * M_PI * x);
                break;
        }
        
        data[i] *= window_coef;
    }
    
    return ERROR_SUCCESS;
}

// 进行傅里叶变换（简化版FFT实现）
// 实际应用中应使用优化的FFT库如FFTW
int perform_fft(const float* input, float* output, int size) {
    if (!input || !output || size <= 0) {
        return ERROR_AUDIO_FRAME_INVALID;
    }
    
    // 这里是FFT的简化实现，实际应用中应使用专业的FFT库
    // 简单起见，这里仅复制输入到输出并进行简单变换
    for (int i = 0; i < size; i++) {
        output[i] = input[i];
    }
    
    // TODO: 实现真正的FFT算法或调用FFT库
    
    return ERROR_SUCCESS;
}

// 计算频谱能量
float calculate_spectrum_energy(const float* spectrum, int size) {
    if (!spectrum || size <= 0) {
        return 0.0f;
    }
    
    float energy = 0.0f;
    for (int i = 0; i < size / 2; i++) {  // 只使用频谱的一半（实部）
        energy += spectrum[i] * spectrum[i];
    }
    
    return energy / (size / 2);
}

// 计算特定频段能量
float calculate_band_energy(const float* spectrum, int size, 
                          float start_freq, float end_freq, 
                          int sample_rate) {
    if (!spectrum || size <= 0 || sample_rate <= 0) {
        return 0.0f;
    }
    
    // 频率分辨率
    float freq_resolution = (float)sample_rate / size;
    
    // 计算频率对应的下标
    int start_bin = (int)(start_freq / freq_resolution);
    int end_bin = (int)(end_freq / freq_resolution);
    
    // 限制范围
    if (start_bin < 0) start_bin = 0;
    if (end_bin >= size / 2) end_bin = size / 2 - 1;
    if (start_bin > end_bin) return 0.0f;
    
    // 计算能量
    float energy = 0.0f;
    for (int i = start_bin; i <= end_bin; i++) {
        energy += spectrum[i] * spectrum[i];
    }
    
    return energy / (end_bin - start_bin + 1);
} 